/**
 * 
 */
package com.bbva.kyfb.kyfbbofi;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.bbva.jee.arq.spring.core.contexto.ArqSpringContext;
import com.bbva.jee.arq.spring.core.gce.ExcepcionEjecucionAplicacion;
import com.bbva.jee.arq.spring.core.log.I18nLog;
import com.bbva.jee.arq.spring.core.log.I18nLogFactory;
import com.bbva.jee.arq.spring.core.util.excepciones.PropiedadNoEncontradaExcepcion;
import com.bbva.kyfb.kyfbdaofi.IFirmasDao;
import com.bbva.kyfb.kyfbdaohost.sistemasHost.AccesoSistemasHost;
import com.bbva.kyfb.kyfbdto.firmas.bo.ComponentePutFirma;
import com.bbva.kyfb.kyfbdto.firmas.bo.ConsultaEmpresaAsociadasNifDto;
import com.bbva.kyfb.kyfbdto.firmas.bo.ConsultaEmpresaAsociadasRefDto;
import com.bbva.kyfb.kyfbdto.firmas.bo.DatosPAU;
import com.bbva.kyfb.kyfbdto.firmas.bo.EmpresaNifOutDto;
import com.bbva.kyfb.kyfbdto.firmas.bo.EmpresaRefOutDto;
import com.bbva.kyfb.kyfbdto.firmas.bo.FicheroInfo;
import com.bbva.kyfb.kyfbdto.firmas.bo.FicheroPdteFirma;
import com.bbva.kyfb.kyfbdto.firmas.bo.FirmaComponente;
import com.bbva.kyfb.kyfbdto.firmas.bo.FirmanteInfo;
import com.bbva.kyfb.kyfbdto.firmas.bo.ListNData;
import com.bbva.kyfb.kyfbdto.firmas.bo.OrdenMifidInDto;
import com.bbva.kyfb.kyfbdto.firmas.bo.OrdenMifidOutDto;
import com.bbva.kyfb.kyfbdto.firmas.bo.UpdateInfoInDto;
import com.bbva.kyfb.kyfbdto.firmas.errores.Errores_kyfb_servicios;
import com.bbva.kyfb.kyfbdto.firmas.filtros.FiltroFicheros;
import com.bbva.kyfb.kyfbdto.firmas.sistemasHost.ConfirmacionProcesoOutDto;
import com.bbva.kyfb.kyfbdto.firmas.sistemasHost.ConsultaAptitudMifidInDto;
import com.bbva.kyfb.kyfbdto.firmas.sistemasHost.ConsultaAptitudMifidOutDto;
import com.bbva.kyfb.kyfbdto.firmas.sistemasHost.ConsultaDatosClienteInDto;
import com.bbva.kyfb.kyfbdto.firmas.sistemasHost.ConsultarFirmatesFicheroOutDto;
import com.bbva.kyfb.kyfbdto.firmas.sistemasHost.DatosClienteDto;
import com.bbva.kyfb.kyfbdto.firmas.sistemasHost.DetalleFicherosPendientesDto;
import com.bbva.kyfb.kyfbdto.firmas.sistemasHost.EliminarFicheroPendienteInDto;
import com.bbva.kyfb.kyfbdto.firmas.sistemasHost.EmpresasFirOutNifDto;
import com.bbva.kyfb.kyfbdto.firmas.sistemasHost.EmpresasFirOutRefDto;
import com.bbva.kyfb.kyfbdto.firmas.sistemasHost.FicherosPendientePorEmpresaNifInDto;
import com.bbva.kyfb.kyfbdto.firmas.sistemasHost.FicherosPendientesEmpresaOutDto;
import com.bbva.kyfb.kyfbdto.firmas.sistemasHost.FirmaFicheroInDto;
import com.bbva.kyfb.kyfbdto.firmas.sistemasHost.FirmarFicheroPendienteInDto;
import com.bbva.kyfb.kyfbdto.firmas.sistemasHost.FirmarFicheroPendienteOutDto;
import com.bbva.kyfb.kyfbdto.firmas.sistemasHost.LineaDetalleDto;
import com.bbva.kyfb.kyfbdto.firmas.sistemasHost.OrdenPendienteFirmaInDto;
import com.bbva.kyfb.kyfbdto.firmas.sistemasHost.OrdenPendienteFirmaRefNifInDto;
import com.bbva.kyfb.kyfbdto.firmas.sistemasHost.OrdenPendienteFirmaRefNifOutDto;
import com.bbva.kyfb.kyfbdto.firmas.sistemasHost.OrdenPendienteFirmaReferenciaExternaInDto;
import com.bbva.kyfb.kyfbdto.firmas.sistemasHost.OrdenPendienteFirmaReferenciaExternaOutDto;
import com.bbva.kyfb.kyfbdto.firmas.sistemasHost.OrdenesPenFirmaRefExternaDto;
import com.bbva.kyfb.kyfbdto.firmas.sistemasHost.UsuariosFirmaOrdenDto;
import com.bbva.kyfb.kyfbdto.firmas.sistemasHost.UsuariosFirmantesOrdenOutDto;
import com.bbva.kyfb.kyfbjpatlbh.dominiotlbh.Ttlsbsfo;
import com.bbva.kyfb.kyfbjpatlsb.dominiotlsb.Ttlsbfrf;
import com.bbva.kyfb.kyfbofi.converters.DtoBoifToDtoConverter;
import com.bbva.kyfb.kyfbofi.converters.DtoToDtoBofiConverter;
import com.bbva.kyfb.kyfbofi.converters.ResulSetDtoConverter;
import com.bbva.kyfb.kyfbofi.objects.Producto;
import com.bbva.kyfb.kyfbutils.constantes.ConstantesFO;
import com.bbva.kyfb.kyfbutils.constantes.UtilFO;
import com.bbva.kyfb.kyfbutils.dao.DaoUtils;
import com.bbva.kyfb.kyfbutils.mifid.MifidFunctions;
import com.bbva.kyfb.kyfbutils.pau.FuncionesPAU;
import com.bbva.kytv.dto.kygu.UsuarioEmpresaDTO;

/**
 * The Class ServicioFirmasBoHostUtil.
 *
 * @author xe20973
 */
@Service("servicioFirmasBoHostUtil")
public class ServicioFirmasBoHostUtil {

	/** Variable LOG. */
	private static final I18nLog LOG = I18nLogFactory.getLogI18n(ServicioFirmasBoHostUtil.class);

	/** The acceso sistemas host. */
	@Autowired
	private AccesoSistemasHost accesoSistemasHost;

	/** The servicio firmas bo util. */
	@Autowired
	private ServicioFirmasBoUtil servicioFirmasBoUtil;

	/** The servicio firmas bo util. */
	@Autowired
	private ServicioFirmasBoClientsUtil servicioFirmasClientsUtil;

	/** The servicio firmas dao. */
	@Autowired
	private IFirmasDao servicioFirmasDao;

	/**
	 * Gets the componente tipo mifid.
	 *
	 * @param ordenMifidInDto the orden mifid in dto
	 * @return the componente tipo mifid
	 * @throws NumberFormatException the number format exception
	 * @throws PropiedadNoEncontradaExcepcion the propiedad no encontrada excepcion
	 */
	public OrdenMifidOutDto getComponenteTipoMifid(final OrdenMifidInDto ordenMifidInDto) throws NumberFormatException, PropiedadNoEncontradaExcepcion {
		final OrdenMifidOutDto ordenMifidOutDto = new OrdenMifidOutDto();

		final List<Object[]> productosObject = servicioFirmasDao.findProductoByCodProdAndCodIdom(
				MifidFunctions.getCodProd(ordenMifidInDto.getTipoOrden()),Integer.parseInt(ordenMifidInDto.getIdioma()));

		final List<Producto> productosDto = new ArrayList<Producto>();

		Producto producto = null;
		for (final Object[] result : productosObject) {
			productosDto.add(ResulSetDtoConverter.resulSetToProductoDto(result));
		}
		if (!CollectionUtils.isEmpty(productosDto)) {
			producto = productosDto.get(0);
		}
		/*
		 * LLamamos a la transaccion para sacar los datos del cliente
		 * TLSMT298
		 */
		final ConsultaDatosClienteInDto consultaDatosInDto = DtoBoifToDtoConverter.ordenMifidInDtoToConsultaDatosClienteInDto(ordenMifidInDto);
		final DatosClienteDto datosClienteDto = accesoSistemasHost.consultarDatosCliente(consultaDatosInDto);
		final ConsultaAptitudMifidInDto consultaAptitudMifidInDto = DtoBoifToDtoConverter.ordenMifidInDtoToConsultaAptitudMifidInDto(ordenMifidInDto, producto, datosClienteDto);
		final ConsultaAptitudMifidOutDto consultaAptitudMifidOutDto = accesoSistemasHost.consultaAptitudMifid(consultaAptitudMifidInDto);
		ordenMifidOutDto.setTipoMifid(consultaAptitudMifidOutDto.getXsnTipoMifid());
		return ordenMifidOutDto;
	}

	/**
	 * Gets the consulta empresas asociadas por nif.
	 *
	 * @param consultaEmpresaAsociadasNifDto the consulta empresa asociadas nif dto
	 * @return the consulta empresas asociadas por nif
	 * @throws ExcepcionEjecucionAplicacion the excepcion ejecucion aplicacion
	 */
	public EmpresaNifOutDto getConsultaEmpresasAsociadasPorNif(final ConsultaEmpresaAsociadasNifDto consultaEmpresaAsociadasNifDto) throws ExcepcionEjecucionAplicacion {
		// Lamada a la 762
		final EmpresasFirOutNifDto empresas = accesoSistemasHost.consultarEmpresasPorNif(DtoBoifToDtoConverter.apoderadoEmpresasDtoToConsultaEmpresaAsociadasNifDto(consultaEmpresaAsociadasNifDto));
		return DtoToDtoBofiConverter.empresaFirmOutNifToEmpresaNifOutDto(empresas);
	}

	/**
	 * Gets the consulta empresas asociadas por referencia.
	 *
	 * @param consultaEmpresaAsociadasRefDto the consulta empresa asociadas ref dto
	 * @return the consulta empresas asociadas por referencia
	 * @throws ExcepcionEjecucionAplicacion the excepcion ejecucion aplicacion
	 */
	public EmpresaRefOutDto getConsultaEmpresasAsociadasPorReferencia(final ConsultaEmpresaAsociadasRefDto consultaEmpresaAsociadasRefDto) throws ExcepcionEjecucionAplicacion {
		// Llamada a la 761
		final EmpresasFirOutRefDto empresas = accesoSistemasHost.consultarEmpresasPorReferencia(DtoBoifToDtoConverter.apoderadoEmpresasDtoToConsultaEmpresaAsociadasRefDto(consultaEmpresaAsociadasRefDto));
		return DtoToDtoBofiConverter.empresaFirmOutRefToEmpresaRefOutDto(empresas);
	}

	/**
	 * Gets the componentes pendientes referencia host.
	 *
	 * @param file the file
	 * @return the componentes pendientes referencia host
	 */
	public ListNData<FicheroPdteFirma,String[]> getComponentesPendientesReferenciaHost(final FicheroInfo file) {

		final String[] servTimeStmps = getServTimeStmps(file);
		final FiltroFicheros filtro = servicioFirmasBoUtil.createFiltroFromDto(file);
		final boolean hasCodUsuario = filtro.getCodUsuario() != null;
		final List<FicheroPdteFirma> result = ResulSetDtoConverter.createFicherosPdteDtoFromEntity(servicioFirmasDao.findComponentesPdteReferenciaTimFichero(file.getCodClienteCash(),file.getCodAplicacion(),filtro, hasCodUsuario, servTimeStmps));
		return new ListNData<FicheroPdteFirma,String[]>(result,servTimeStmps);
	}

	/**
	 * {@inheritDoc}
	 * @see com.bbva.kyfb.kyfbbofi.IFirmasBo#getComponentesPendientesReferenciaHost(com.bbva.kyfb.kyfbdto.firmas.bo.FicheroInfo)
	 */
	public int getTotalComponentesPdtesReferenciaHost(final FicheroInfo file, final FiltroFicheros filtro, final boolean hasCodUsuario, final String[] servTimeStmps) {

		return servicioFirmasDao.getTotalComponentesPdtesReferenciaHost(
				file.getCodClienteCash(), file.getCodAplicacion(), filtro,
				hasCodUsuario,servTimeStmps);
	}

	private String[] getServTimeStmps(final FicheroInfo file){
		final OrdenPendienteFirmaReferenciaExternaInDto opfredto = DtoBoifToDtoConverter.ficheroInfoToOrdenPendienteFirmaReferenciaExternaInDto(file);
		final OrdenPendienteFirmaReferenciaExternaOutDto ordenPendienteFirmaReferenciaExternaOutDto = accesoSistemasHost.consultarOrdenPendienteFirmaReferenciaExterna(opfredto);
		final FicherosPendientesEmpresaOutDto ficherosPendientesEmpresaOutDto = accesoSistemasHost.consultarFicherosPendientesPorEmpresa(DtoBoifToDtoConverter.ficheroInfoToFicherosPendienteEmpresaInDto(file));

		List<String> lstTimeStmp;
		try {
			lstTimeStmp = UtilFO.convertirFechasTxToBBDD(filterServTimeStmps(ordenPendienteFirmaReferenciaExternaOutDto, ficherosPendientesEmpresaOutDto));
		} catch (final ParseException e) {
			throw new ExcepcionEjecucionAplicacion(Errores_kyfb_servicios.FORMATO_INCORRECTO,e);
		}
		return Arrays.copyOf(lstTimeStmp.toArray(),lstTimeStmp.toArray().length,String[].class);
	}

	/**
	 * Delete componente pendiente host.
	 *
	 * @param usuario the usuario
	 * @param nif the nif
	 * @param ficheroBorrado the fichero borrado
	 * @param tipoFirma the tipo firma
	 */
	public void deleteComponentePendienteHost(final DatosPAU usuario, final String nif, final FicheroPdteFirma ficheroBorrado, final String tipoFirma) {
		
		if (ConstantesFO.SIGLAS_FIRMA_HOST.equalsIgnoreCase(tipoFirma)) {
			final String[] nifs = nif.split("\\|");
			if(nifs.length!=3 || nifs[0].isEmpty() || nifs[1].isEmpty()) {
				throw new ExcepcionEjecucionAplicacion(Errores_kyfb_servicios.CAMPO_OBLIGATORIO_NO_INFORMADO);
			}
			if (ConstantesFO.ORDEN_ONLINE.equalsIgnoreCase(ficheroBorrado.getModoOrden())) {
				final OrdenPendienteFirmaInDto ordenPendienteInDto = new OrdenPendienteFirmaInDto();
				ordenPendienteInDto.setBancsbEntr(Integer.parseInt(ArqSpringContext.getContextoEscritorio().getPerfil().getBancoFisico()));
				ordenPendienteInDto.setCanalEntr(Integer.parseInt(usuario.getsCanal()));
				
				ordenPendienteInDto.setCdnitrEntr(nifs[0]);
				ordenPendienteInDto.setRefeexteEntr(usuario.getsReferencia());
				ordenPendienteInDto.setTimestampEntr(ficheroBorrado.getdFechaCreacion().toString());
				accesoSistemasHost.eliminarOrdenPendienteFirma(ordenPendienteInDto);
			} else {
				final EliminarFicheroPendienteInDto eliminarFicheroPendienteInDto = new EliminarFicheroPendienteInDto();
				eliminarFicheroPendienteInDto.setBancsbSolici(Integer.parseInt(ArqSpringContext.getContextoEscritorio().getPerfil().getBancoFisico()));
				eliminarFicheroPendienteInDto.setCanalSstt(Integer.parseInt(usuario.getsCanal()));
				eliminarFicheroPendienteInDto.setClienteSolici(Integer.parseInt(nifs[1]));
				eliminarFicheroPendienteInDto.setComrefex(ConstantesFO.FIRMA_HOST);
				eliminarFicheroPendienteInDto.setDniSolici(nifs[0]);
				eliminarFicheroPendienteInDto.setFormatoAsunto(ConstantesFO.FORMATO_ASUNTO);
				eliminarFicheroPendienteInDto.setHueco1(ConstantesFO.VACIO);
				eliminarFicheroPendienteInDto.setHueco2(ConstantesFO.VACIO);
				eliminarFicheroPendienteInDto.setHueco3(ConstantesFO.VACIO);
				eliminarFicheroPendienteInDto.setRefeexte(usuario.getsReferencia());
				eliminarFicheroPendienteInDto.setTimestampSolic(ficheroBorrado.getdFechaCreacion().toString());
				eliminarFicheroPendienteInDto.setTipoAccion(ConstantesFO.TIPO_ACCION_DELETE);
				eliminarFicheroPendienteInDto.setVersionSstt(ConstantesFO.VERSIONSSTT);
				accesoSistemasHost.eliminarFicheroPendienteFirma(eliminarFicheroPendienteInDto);
			}
		}
	}

	/**
	 * Gets the ids componentes.
	 *
	 * @param file the file
	 * @return the ids componentes
	 */
	public List<String> getIdsComponentes(final FicheroInfo file) {
		List<String> idComponentes= null;
		final OrdenPendienteFirmaRefNifInDto nifIn = DtoBoifToDtoConverter.ficheroInfoToOrdenPendienteFirmaRefNifInDto(file);
		//recuperamos las ordenes online para la referencia.
		final OrdenPendienteFirmaRefNifOutDto ordenesNifOut = accesoSistemasHost.consultarOrdenPendienteFirma(nifIn);
		//Recuperamos los ficheros pendientes para la referencia.
		final FicherosPendientePorEmpresaNifInDto ficherosPendientesRef= DtoBoifToDtoConverter.ficheroInfoToFicherosPendientePorEmpresaNifInDto(file);
		final FicherosPendientesEmpresaOutDto ficherosNifOut=accesoSistemasHost.consultarFicherosPendientesPorEmpresaNif(ficherosPendientesRef);
		idComponentes= new ArrayList<String>();
		if(ordenesNifOut != null && ordenesNifOut.getLineaDetalle() != null){
			for(final LineaDetalleDto linea:ordenesNifOut.getLineaDetalle()) {
				idComponentes.add(linea.getTimAltaoprSal());
			}
		}
		if(ficherosNifOut != null && ficherosNifOut.getTablaDetalleFichero() != null) {
			for(final DetalleFicherosPendientesDto detalle: ficherosNifOut.getTablaDetalleFichero()) {
				idComponentes.add(detalle.getTimestampClien());
			}
		}

		return idComponentes;
	}


	/**
	 * Gets the usuarios firma realizada.
	 *
	 * @param lista the lista
	 * @param file the file
	 * @return the usuarios firma realizada
	 */
	public List<FirmanteInfo> getUsuariosFirmaRealizada(final List<FirmanteInfo> lista, final FicheroInfo file) {
		final List<FirmanteInfo> listaFirmantes = lista;
		final FiltroFicheros filtro = servicioFirmasBoUtil.createFiltroFromDto(file);
		// Recuperamos de base de datos el fichero de firma pendiente
		final FicheroPdteFirma ficheroPdte = ResulSetDtoConverter.createFicherosPdteDtoFromEntity(servicioFirmasDao.findComponentesPdteReferencia(file.getCodClienteCash(),file.getCodAplicacion(), filtro, filtro.getCodUsuario()!=null?true:false)).get(0);

		if (ConstantesFO.ORDEN_ONLINE.equalsIgnoreCase(ficheroPdte.getModoOrden())) {

			final UsuariosFirmantesOrdenOutDto usuariosFirmantesOrdenOutDto = accesoSistemasHost.consultarUsuariosFirmantesOrden(
					DtoBoifToDtoConverter.ficheroInfoToUsuariosFirmantesOrdenInDto(file, ficheroPdte));

			if (usuariosFirmantesOrdenOutDto != null && usuariosFirmantesOrdenOutDto.getListaUsuarioFirmaOrden() != null) {
				for (final UsuariosFirmaOrdenDto detalleUsuario : usuariosFirmantesOrdenOutDto.getListaUsuarioFirmaOrden()) {
					for (final FirmanteInfo firmanteInfo : listaFirmantes) {
						if (firmanteInfo.getCodDocumentoUsuario().equalsIgnoreCase(detalleUsuario.getCdnitrSal())) {
							listaFirmantes.remove(firmanteInfo);
						}
					}
				}
			}

			// Si no llamamos a la transacion TxTLSMT775-1-5-1
		} else {
			final ConsultarFirmatesFicheroOutDto consultarFirmatesFicheroOutDto = accesoSistemasHost.consultarFirmantesFichero(
					DtoBoifToDtoConverter.ficheroInfoToConsultarFirmatesFicheroInDto(file, ficheroPdte));

			removeUsuariosFirmatesFichero(listaFirmantes, consultarFirmatesFicheroOutDto);
		}

		//TODO: InformacionUsuarios.buscarUsuarios pasando el canal, bancoInterno y referencia.
		//canal = file.getCodClienteCash().substring(0, 4);
		//bancoInt = file.getCodClienteCash().substring(4, 8);
		//referencia = file.getCodClienteCash().substring(8, 16);

		return listaFirmantes;
	}


	/**
	 * Gets the usuarios firma pedte host.
	 *
	 * @param file the file
	 * @return the usuarios firma pedte host
	 */
	public List<FirmanteInfo> getUsuariosFirmaPedteHost(final FicheroInfo file, final FicheroPdteFirma ficheroPdte) {
		List<FirmanteInfo> listaFirmantes = null;

		// En firmas host, no hay que comprobar los usuarios que pueden firmas las ordenes, simplemente se devuelve el listado de todos
		//los usuarios firmantes de la referencia
		final List<UsuarioEmpresaDTO> listaUsuariosFirmantes = servicioFirmasClientsUtil.getUsuariosFirmantesReferenciaHost(ficheroPdte, file, file.getCodClienteCash());
		DaoUtils.atLeastOneRecord(listaUsuariosFirmantes);

		listaFirmantes = getListaAuditoresFirmates(listaUsuariosFirmantes);

		if (ConstantesFO.ORDEN_ONLINE.equalsIgnoreCase(ficheroPdte.getModoOrden())) {
			// Si es orden online llamamos a la transacion TxTLSMT775-1-5-1
			final UsuariosFirmantesOrdenOutDto usuariosFirmantesOrdenOutDto = accesoSistemasHost.consultarUsuariosFirmantesOrden(DtoBoifToDtoConverter.ficheroInfoToUsuariosFirmantesOrdenInDto(file, ficheroPdte));
			removeUsuariosFirmantesOrden(listaFirmantes, usuariosFirmantesOrdenOutDto);
		} else {
			// Si es fichero llamamos a la transaccion TxTLSMT768-1-1-1
			final ConsultarFirmatesFicheroOutDto consultarFirmatesFicheroOutDto = accesoSistemasHost.consultarFirmantesFichero(DtoBoifToDtoConverter.ficheroInfoToConsultarFirmatesFicheroInDto(file, ficheroPdte));
			removeUsuariosFirmatesFichero(listaFirmantes, consultarFirmatesFicheroOutDto);
		}

		// Vamos a insertar y generar el numero aleatorio
		final Map<String, String> numerosAleatorios = servicioFirmasDao.findNumAleatorioFRF(ficheroPdte.getdFechaCreacion().toString());

		for (final FirmanteInfo firmante : listaFirmantes) {
			if (numerosAleatorios.containsKey(firmante.getCodDocumentoUsuario())) {
				firmante.setNumeroAleatorio(numerosAleatorios.get(firmante.getCodDocumentoUsuario()));
			} else {
				// Generamos un nuevo numero aleatorio
				final String nuevoNumAleatorio = Long.toString(FuncionesPAU.getReferenciaNPosiciones(UtilFO.LONGITUD_NUM_ALEATORIO));
				firmante.setNumeroAleatorio(nuevoNumAleatorio);
				ficheroPdte.setsNumeroAleatorio(nuevoNumAleatorio);
				file.setsNifDni(firmante.getCodDocumentoUsuario());
				final Ttlsbfrf frf = ResulSetDtoConverter.formarFRF(ficheroPdte, file);
				try {
					servicioFirmasDao.insertFRF(frf);
				} catch (final ExcepcionEjecucionAplicacion ex) {
					LOG.warn("ServicioFirmasBoHostUtil - Se ha producido un error al insertar en la FRF");
				}
			}
		}

		return listaFirmantes;
	}

	/**
	 * Firmar orden online.
	 *
	 * @param firmaComponente the firma componente
	 * @param fichero the fichero
	 */
	public void firmarOrdenOnline(final FirmaComponente firmaComponente, final FicheroPdteFirma fichero) {
		//Si es online llamamos a la transaccion TLSMT775-1-4-1
		final OrdenPendienteFirmaInDto ordenPendienteInDto = new OrdenPendienteFirmaInDto();
		//TODO de verdad hay que cogerlo de arquitectura?
		ordenPendienteInDto.setBancsbEntr(Integer.parseInt(ArqSpringContext.getContextoEscritorio().getPerfil().getBancoFisico()));
		ordenPendienteInDto.setCanalEntr(Integer.parseInt(firmaComponente.getDatosPAU().getsCanal()));
		ordenPendienteInDto.setCdnitrEntr(firmaComponente.getsNIFUsuario());
		ordenPendienteInDto.setRefeexteEntr(firmaComponente.getDatosPAU().getsReferencia());
		ordenPendienteInDto.setTimestampEntr(fichero.getdFechaCreacion().toString());
		final ConfirmacionProcesoOutDto salida = accesoSistemasHost.firmarOrdenPendienteFirma(ordenPendienteInDto);

		// Actualizamos el estado segun la salida que devuelve la transaccion
		if(salida == null || StringUtils.isBlank(salida.getTipoMensaje())){
			if(salida.getCodigoAviso().equalsIgnoreCase("457")) {
				throw new ExcepcionEjecucionAplicacion(Errores_kyfb_servicios.NO_EXISTEN_ORDENES_PENDIENTES);
			}else if(salida.getCodigoAviso().equalsIgnoreCase("306")){
				throw new ExcepcionEjecucionAplicacion(Errores_kyfb_servicios.NO_EXISTEN_DATOS_DE_LA_ORDEN_PENDIENTE);
			}else {
				throw new ExcepcionEjecucionAplicacion(Errores_kyfb_servicios.SERVICIO_NO_DISPONIBLE);
			}
		}

		if(salida.getTipoMensaje().trim().equals("2")){
			fichero.setsCodEstadoFichero(UtilFO.EST_FDO_PARCIAL);
		}else if( salida.getTipoMensaje().trim().equals("1") ){
			fichero.setsCodEstadoFichero(UtilFO.EST_ENV_ASISTENTE);
		}else {
			throw new ExcepcionEjecucionAplicacion(Errores_kyfb_servicios.ERROR_EN_EL_INTENTO_DE_EJCUCION_DE_LA_ORDEN);
		}
	}

	/**
	 * Removes the usuarios firmates fichero.
	 *
	 * @param listaFirmantes the lista firmantes
	 * @param consultarFirmatesFicheroOutDto the consultar firmates fichero out dto
	 */
	private void removeUsuariosFirmatesFichero(final List<FirmanteInfo> listaFirmantes, final ConsultarFirmatesFicheroOutDto consultarFirmatesFicheroOutDto) {
		if (consultarFirmatesFicheroOutDto != null && consultarFirmatesFicheroOutDto.getListaDetalleUsuarioFichero() != null) {
			for (final com.bbva.kyfb.kyfbdto.firmas.sistemasHost.DetalleUsuarioFicheroDto detalleUsuario : consultarFirmatesFicheroOutDto.getListaDetalleUsuarioFichero()) {
				final String documentoUsuario = detalleUsuario.getDniFichero();
				removeFirmante(listaFirmantes, documentoUsuario);
			}
		}
	}

	/**
	 * Removes the usuarios firmantes orden.
	 *
	 * @param listaFirmantes the lista firmantes
	 * @param usuariosFirmantesOrdenOutDto the usuarios firmantes orden out dto
	 */
	private void removeUsuariosFirmantesOrden(final List<FirmanteInfo> listaFirmantes, final UsuariosFirmantesOrdenOutDto usuariosFirmantesOrdenOutDto) {
		if (usuariosFirmantesOrdenOutDto != null && usuariosFirmantesOrdenOutDto.getListaUsuarioFirmaOrden() != null) {
			for (final UsuariosFirmaOrdenDto detalleUsuario : usuariosFirmantesOrdenOutDto.getListaUsuarioFirmaOrden()) {
				final String documentoUsuario = detalleUsuario.getCdnitrSal();
				removeFirmante(listaFirmantes, documentoUsuario);
			}
		}
	}

	/**
	 * Removes the firmante.
	 *
	 * @param listaFirmantes the lista firmantes
	 * @param documentoUsuario the documento usuario
	 */
	private void removeFirmante(final List<FirmanteInfo> listaFirmantes,final String documentoUsuario) {
		final List<FirmanteInfo> listaFirmantesOriginal = new ArrayList<FirmanteInfo>();
		listaFirmantesOriginal.addAll(listaFirmantes);
		for (final FirmanteInfo firmanteInfo : listaFirmantesOriginal) {
			if (firmanteInfo.getCodDocumentoUsuario().equalsIgnoreCase(documentoUsuario)) {
				listaFirmantes.remove(firmanteInfo);
			}
		}
	}

	/**
	 * Gets the lista auditores firmates.
	 *
	 * @param listaUsuariosAuditores the lista usuarios auditores
	 * @return the lista auditores firmates
	 */
	private List<FirmanteInfo> getListaAuditoresFirmates(final List<UsuarioEmpresaDTO> listaUsuariosAuditores) {
		final List<FirmanteInfo> listaFirmantes = new ArrayList<FirmanteInfo>();
		FirmanteInfo auditor;
		for (final UsuarioEmpresaDTO usuarioAuditor : listaUsuariosAuditores) {
			auditor = new FirmanteInfo();
			auditor.setCodUsuario(usuarioAuditor.getCodUsuario());
			auditor.setsNomUsuario(usuarioAuditor.getNomUsuario());
			// tipoValidacion en la primera version va a ir vacio
			auditor.setsTipoValidacion("");
			auditor.setsTipoFirmante(usuarioAuditor.getTipoFirmante());
			auditor.setsTipoFirma(usuarioAuditor.getModFirma());
			auditor.setCodDocumentoUsuario(usuarioAuditor.getCodDocumentoUsuario());
			listaFirmantes.add(auditor);
		}
		return listaFirmantes;
	}

	/**
	 * marchaAtrasHost
	 * Funcion para realizar la llamada de la transaccion que anula los cmabios.
	 *
	 * @param codClienteCash the cod cliente cash
	 * @param fichero the fichero
	 * @param firmaComponente the firma componente
	 */
	public void marchaAtrasHost(final String codClienteCash, final FicheroPdteFirma fichero, final FirmaComponente firmaComponente) {
		//Se hace marcha atras en host
		final FirmaFicheroInDto firmaFicheroInDto = new FirmaFicheroInDto();
		firmaFicheroInDto.setBancsbEntr(Integer.parseInt(ArqSpringContext.getContextoEscritorio().getPerfil().getBancoFisico()));
		firmaFicheroInDto.setCanalEntr(Integer.parseInt(firmaComponente.getDatosPAU().getsCanal()));
		firmaFicheroInDto.setCdnitrEntr(firmaComponente.getsNIFUsuario());
		firmaFicheroInDto.setRefeexteEntr(firmaComponente.getDatosPAU().getsReferencia());
		firmaFicheroInDto.setTimestampEntr(fichero.getdFechaCreacion().toString());
		final ConfirmacionProcesoOutDto salida = accesoSistemasHost.anularFirmaFichero(firmaFicheroInDto);
		LOG.debug("Resultado de accesoSistemasHost.anularFirmaFichero: " + salida.toString());
	}

	/**
	 * marchaAtrasBBDDHost Funcion para volver a dejar las tablas CAB SFO y FRF tal y
	 * como estaban.
	 * @param sfoBck
	 * @param codClienteCash
	 * @param fichero
	 * @param firmaComponente
	 * @param cpf
	 */
	public void marchaAtrasBBDDHost(final Ttlsbsfo sfoBck,
			final String codClienteCash, final FicheroPdteFirma fichero,
			final FirmaComponente firmaComponente, final ComponentePutFirma cpf ) {

		try {
			fichero.setlPesoActual(Double.valueOf(sfoBck.getQnuPesofir().toString()));
			fichero.setsCodEstadoFichero(sfoBck.getCodEstadods());
			actualizarPutFirmaComponenteHost(
					codClienteCash, fichero,
					firmaComponente, cpf, UtilFO.XSN_FIRMADO_N);
		} catch (final Exception e) {
			LOG.warn("ServicioFirmasBoHostUtil.marchaAtrasBBDDHost - Ha dado un error al realizar la marcha atras");
		}


	}


	/**
	 * Firmar fichero no online.
	 *
	 * @param firmaComponente the firma componente
	 * @param fichero the fichero
	 */
	public void firmarFicheroNoOnline(final FirmaComponente firmaComponente, final FicheroPdteFirma fichero) {
		//Si no es online llamamos a la transaccion TLSMT767-1-1-1
		final FirmarFicheroPendienteInDto firmarFicheroPendienteInDto = new FirmarFicheroPendienteInDto();
		//TODO de verdad hay que cogerlo de arquitectura?
		firmarFicheroPendienteInDto.setBancsbSolici(Integer.parseInt(ArqSpringContext.getContextoEscritorio().getPerfil().getBancoFisico()));
		firmarFicheroPendienteInDto.setCanalSstt(Integer.parseInt(firmaComponente.getDatosPAU().getsCanal()));
		firmarFicheroPendienteInDto.setCertifSolici(ConstantesFO.VACIO);
		firmarFicheroPendienteInDto.setComrefex(ConstantesFO.FIRMA_HOST);
		firmarFicheroPendienteInDto.setDniSolici(firmaComponente.getsNIFUsuario());
		firmarFicheroPendienteInDto.setFormatoAsunto(ConstantesFO.FORMATO_ASUNTO);
		firmarFicheroPendienteInDto.setHueco1(ConstantesFO.VACIO);
		firmarFicheroPendienteInDto.setHueco2(ConstantesFO.VACIO);
		firmarFicheroPendienteInDto.setHueco3(ConstantesFO.VACIO);
		firmarFicheroPendienteInDto.setRefeexte(firmaComponente.getDatosPAU().getsReferencia());
		firmarFicheroPendienteInDto.setTimestampSolic(fichero.getdFechaCreacion().toString());
		firmarFicheroPendienteInDto.setTipoAccion(ConstantesFO.TIPO_ACCION_PUT);
		firmarFicheroPendienteInDto.setVersionSstt(ConstantesFO.VERSIONSSTT);

		final FirmarFicheroPendienteOutDto salida = accesoSistemasHost.firmarFicheroPendiente(firmarFicheroPendienteInDto);

		// Actualizamos el estado segun la salida que devuelve la transaccion
		if(salida == null || StringUtils.isBlank(salida.getTipoMensaje())){
			throw new ExcepcionEjecucionAplicacion(Errores_kyfb_servicios.SERVICIO_NO_DISPONIBLE);
		}

		if(salida.getTipoMensaje().trim().equals("2") ){
			fichero.setsCodEstadoFichero(UtilFO.EST_FDO_PARCIAL);
		}else if( salida.getTipoMensaje().trim().equals("3") ){
			fichero.setsCodEstadoFichero(UtilFO.EST_ENV_ASISTENTE);
		}else {
			throw new ExcepcionEjecucionAplicacion(Errores_kyfb_servicios.NIF_INCORRECTO_O_NO_VALIDO_OPERACION);
		}
	}


	/**
	 * Filter serv time stmps.
	 *
	 * @param tipoOrdStrFinal the tipo ord str final
	 * @param ordenPendienteFirmaReferenciaExternaOutDto the orden pendiente firma referencia externa out dto
	 * @param ficherosPendientesEmpresaOutDto the ficheros pendientes empresa out dto
	 * @return the list
	 */
	private List<String> filterServTimeStmps(final OrdenPendienteFirmaReferenciaExternaOutDto ordenPendienteFirmaReferenciaExternaOutDto, final FicherosPendientesEmpresaOutDto ficherosPendientesEmpresaOutDto) {
		final List<String> servTimeStmps = new ArrayList<String>();

		if(ordenPendienteFirmaReferenciaExternaOutDto!=null){
			for (final OrdenesPenFirmaRefExternaDto orden : ordenPendienteFirmaReferenciaExternaOutDto.getListaOrdenesPenFirmaRefExterna()){
				servTimeStmps.add(orden.getTimestampSal());
			}
		}
		if(ficherosPendientesEmpresaOutDto!=null){
			for (final DetalleFicherosPendientesDto detalle : ficherosPendientesEmpresaOutDto.getTablaDetalleFichero()){
				servTimeStmps.add(detalle.getTimestampClien());
			}
		}
		return servTimeStmps;
	}

	/**
	 * Realiza la insercion del numero aleatorio para el fichero indicado (HOST).
	 * Si falla la insercion, se realiza actualizacion en la FRF
	 * @param fichero lleva la informacion del fichero
	 * @param info lleva la informacion de entrada al servicio
	 * @throws ExcepcionEjecucionAplicacion
	 */
	public void insertarActualizarNumeroAleatorio(final FicheroPdteFirma fichero, final UpdateInfoInDto info) throws ExcepcionEjecucionAplicacion {

		final FicheroInfo ficheroInfo = new FicheroInfo();
		ficheroInfo.setsNifDni(info.getsNIFUsuario());
		final Ttlsbfrf frf = ResulSetDtoConverter.formarFRF(fichero, ficheroInfo);

		// Lo insertamos en la tabla FFS
		servicioFirmasDao.insertFRF(frf);
		//LOG.info("ServicioFirmasBoHostUtil.insertarActualizarNumeroAleatorio - Se ha insertado correctamente en la FRF");
	}

	/**
	 * actualizarPutFirmaComponenteHost Actualiza la bbdd al hacer el put de host. Las
	 * tablas afectadas son CAB, SFO, FRF
	 *
	 * @param codClienteCash
	 * @param fichero
	 * @param firmaComponente
	 * @param cf
	 * @param xsnFirmado
	 * @throws PropiedadNoEncontradaExcepcion
	 */
	public void actualizarPutFirmaComponenteHost(final String codClienteCash, final FicheroPdteFirma fichero, final FirmaComponente firmaComponente, final ComponentePutFirma cf , final char xsnFirmado) throws PropiedadNoEncontradaExcepcion {
		// Insertamos en la CAB
		servicioFirmasDao.updateEstadoFichero(UtilFO.getCodNumero(fichero.getsCodEstadoFichero()),codClienteCash, cf.getsTipoOrden().toString(),	cf.getsIdOrdenFirmas());// CAB
		LOG.info("ServicioFirmasBoHostUtil.actualizarPutFirmaComponenteHost - Se ha insertado correctamente en la CAB");
		// Insertamos en la SFO
		servicioFirmasDao.updatePesoEstadoFirma(fichero.getsCodEstadoFichero(), fichero.getlPesoActual(),	codClienteCash, cf.getsTipoOrden().toString(), cf.getsIdOrdenFirmas());// SFO
		LOG.info("ServicioFirmasBoHostUtil.actualizarPutFirmaComponenteHost - Se ha insertado correctamente en la SFO");
		//Insertamos en la FRF
		final Ttlsbfrf frf = ResulSetDtoConverter.formarFRF(fichero, firmaComponente, xsnFirmado);// FRF
		servicioFirmasDao.insertFRF(frf);// FRF
		LOG.info("ServicioFirmasBoHostUtil.actualizarPutFirmaComponenteHost - Se ha insertado correctamente en la FRF");
		// Insertamos en la FFS
		//			Ttlsbffs ffs = ResulSetDtoConverter.formarFFS(fichero, firmaComponente, cf, xsnFirmado);
		//			servicioFirmasDao.insertFirmante(ffs);// FFS

	}

}
